#include "musicplayer.h"
#include "ui_musicplayer.h"
#include <QMouseEvent>
#include <QPushButton>
#include <QGraphicsDropShadowEffect>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
#include <QFileDialog>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQuery>
#include <QSystemTrayIcon>
#include <QMenu>
#include "music.h"

MusicPlayer::MusicPlayer(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MusicPlayer),
      currentIndex(-1),
      isSpeed(false)
{
    ui->setupUi(this);

    // 初始化界面设置
    initUi();
    // 初始化数据库
    initSQLite();
    // 加载歌曲文件
    initMusicList();
    // 初始化播放
    initPlayer();
    // 关联信号和槽
    connectSignalAndSlot();
}

MusicPlayer::~MusicPlayer()
{
    delete ui;
}

void MusicPlayer::initUi()
{
    this->setWindowFlag(Qt::FramelessWindowHint);
    // 窗口背景透明
    this->setAttribute(Qt::WA_TranslucentBackground);
    setWindowIcon(QIcon(":/images/tubiao.png")); // 设置主窗口图标
    ui->max->setEnabled(false);
    // 窗口阴影
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setColor("#0");
    shadowEffect->setOffset(0, 0);
    shadowEffect->setBlurRadius(10);
    ui->background->setGraphicsEffect(shadowEffect);
    // 添加托盘图标
    QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/images/tubiao.png"));
    // 创建托盘菜单
    QMenu* trayMenu = new QMenu(this);
    trayMenu->addAction("显示", this, &QWidget::showNormal);
    trayMenu->addSeparator();
    trayMenu->addAction("退出", this, &MusicPlayer::quitMusicPlayer);
    // 菜单添加到托盘
    trayIcon->setContextMenu(trayMenu);
    // 显示托盘
    trayIcon->show();
    // 初始化自定义按钮
    ui->rec->setIconAndText(":/images/rec.png", "推荐", 0);
    ui->audio->setIconAndText(":/images/radio.png", "电台", 1);
    ui->music->setIconAndText(":/images/music.png", "音乐馆", 2);
    ui->like->setIconAndText(":/images/like.png", "我喜欢", 3);
    ui->local->setIconAndText(":/images/local.png", "本地下载", 4);
    ui->recent->setIconAndText(":/images/recent.png", "最近播放", 5);
    // 本地下载动画显示
    ui->stackedWidget->setCurrentIndex(4);
    currentPage = ui->localPage;
    ui->local->showAnimation(true);
    // 初始化推荐内容
        // 先初始化随机数种子
    srand(time(NULL));
    ui->recMusicBox->InitRecBoxUi(randomPicture(), 1);
    ui->supplyMusicBox->InitRecBoxUi(randomPicture(), 2);
    // 设置本地，喜欢，最近播放页面
    ui->likePage->setCommonPageUi("我喜欢", ":/images/ilikebg.png");
    ui->localPage->setCommonPageUi("本地音乐", ":/images/localbg.png");
    ui->recentPage->setCommonPageUi("最近播放", ":/images/recentbg.png");
    // 设置播放按钮初始图标
    ui->Play->setIcon(QIcon(":/images/play_2.png"));
    // 默认为随机播放
    ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    // 创建音量调节窗口对象并挂到对象树
    volumeTool = new VolumeTool(this);
    // 歌词窗口，高度705
    lrcPage = new LrcPage(this);
    lrcPage->setGeometry(10, 16, lrcPage->width(), lrcPage->height());
    lrcPage->hide();
    // 初始化动画
    lrcAnimation = new QPropertyAnimation(lrcPage, "geometry", this);
    lrcAnimation->setDuration(250);
    lrcAnimation->setStartValue(QRect(10, 16 + lrcPage->height(), lrcPage->width(), lrcPage->height()));
    lrcAnimation->setEndValue(QRect(10, 16, lrcPage->width(), lrcPage->height()));
}

void MusicPlayer::connectSignalAndSlot()
{
    connect(ui->rec, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);
    connect(ui->audio, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);
    connect(ui->music, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);
    connect(ui->like, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);
    connect(ui->local, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);
    connect(ui->recent, &BtForm::btClick, this, &MusicPlayer::onBtFormClick);

    // 关联CommonPage发射的updateLikeMusic信号
    connect(ui->likePage, &CommonPage::updateLikeMusic, this,&MusicPlayer::onUpdateLikeMusic);
    connect(ui->localPage, &CommonPage::updateLikeMusic, this,&MusicPlayer::onUpdateLikeMusic);
    connect(ui->recentPage, &CommonPage::updateLikeMusic, this,&MusicPlayer::onUpdateLikeMusic);   
}

QJsonArray MusicPlayer::randomPicture()
{
    QVector<QString> vecImage;
    vecImage << "001.png" << "003.png" << "004.png" << "005.png"
             << "006.png" <<"007.png" << "008.png" << "009.png"
             << "010.png" << "011.png" <<"012.png" << "013.png"
             << "014.png" << "015.png" << "016.png" << "017.png"
             << "018.png" << "019.png" << "020.png" << "021.png"
             << "022.png" << "023.png" << "024.png" << "025.png"
             <<"026.png" << "027.png" << "028.png" << "029.png"
             << "030.png" <<"031.png" << "032.png" << "033.png"
             << "034.png" << "035.png" << "036.png" << "037.png"
             << "038.png" << "039.png" << "040.png";
    // 打乱图片顺序
    std::random_shuffle(vecImage.begin(), vecImage.end());

    QJsonArray objArray;
    for (int i = 0; i < vecImage.size(); i++)
    {
        QJsonObject obj;
        obj.insert("path", ":/images/rec/" + vecImage[i]);
        QString text = QString("推荐-%1").arg(i + 1, 3, 10, QChar('0'));
        obj.insert("text", text);

        objArray.append(obj);
    }

    return objArray;

}

void MusicPlayer::initPlayer()
{
    player = new QMediaPlayer(this);
    playList = new QMediaPlaylist(this);
    // 设置默认循环播放
    playList->setPlaybackMode(QMediaPlaylist::Loop);
    // 播放列表设置
    player->setPlaylist(playList);
    // 默认音量20
    player->setVolume(40);
    // 关联状态信号
    connect(player, &QMediaPlayer::stateChanged, this, &MusicPlayer::onPlayStateChanged);
    // 播放模式图片
    connect(playList, &QMediaPlaylist::playbackModeChanged, this,&MusicPlayer::onPlaybackModeChanged);
    // 播放所有点击信号
    connect(ui->likePage, &CommonPage::playAll, this, &MusicPlayer::onPlayAll);
    connect(ui->localPage, &CommonPage::playAll, this, &MusicPlayer::onPlayAll);
    connect(ui->recentPage, &CommonPage::playAll, this, &MusicPlayer::onPlayAll);
    // 双击
    connect(ui->likePage, &CommonPage::playMusicByIndex, this,&MusicPlayer::playMusicByIndex);
    connect(ui->localPage, &CommonPage::playMusicByIndex, this,&MusicPlayer::playMusicByIndex);
    connect(ui->recentPage, &CommonPage::playMusicByIndex, this,&MusicPlayer::playMusicByIndex);
    // 当前播放改变
    connect(playList, &QMediaPlaylist::currentIndexChanged, this, &MusicPlayer::onCurrentIndexChanged);
    // 静音
    connect(volumeTool, &VolumeTool::setSilence, this, &MusicPlayer::setMusicSilence);
    // 设置音量
    connect(volumeTool, &VolumeTool::setMusicVolume, this, &MusicPlayer::setPlayerVolume);
    // 总时间更新
    connect(player, &QMediaPlayer::durationChanged, this, &MusicPlayer::onDurationChanged);
    // 当前播放时间
    connect(player, &QMediaPlayer::positionChanged, this, &MusicPlayer::onPositionChanged);
    // 设置播放进度
    connect(ui->processBar, &MusicSlider::setMusicSliderPosition, this, &MusicPlayer::onMusicSliderChanged);
    // 媒体源改变
    connect(player, &QMediaPlayer::metaDataAvailableChanged, this, &MusicPlayer::onMetaDataAvailableChanged);
}

void MusicPlayer::initSQLite()
{
    // 创建数据库
    sqlite = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    sqlite.setDatabaseName("MusicPlayer.db");
    // 打开数据库
    if (!sqlite.open())
    {
        QMessageBox::critical(this, "打开数据库失败", sqlite.lastError().text());
        return;
    }

    qDebug() << "数据库连接成功";

    // 创建数据表
    QString sql = "CREATE TABLE IF NOT EXISTS musicInfo(\
                   id INTEGER PRIMARY KEY AUTOINCREMENT,\
                   musicId varchar(200) UNIQUE,\
                   musicName varchar(50),\
                   musicSinger varchar(50),\
                   musicAlbum varchar(50),\
                   duration BIGINT,\
                   musicUrl varchar(50),\
                   isLike TINYINT(1),\
                   isHistory TINYINT(1));";
    QSqlQuery query;
    if (!query.exec(sql))
    {
        QMessageBox::critical(this, "创建表失败", query.lastError().text());
        return;
    }

    qDebug() << "创建成功";
}

void MusicPlayer::initMusicList()
{
    musicList.readFromDB();
    // 更新页面
    ui->likePage->setMusicListType(PageType::LIKE_PAGE);
    ui->likePage->reFresh(musicList);
    ui->localPage->setMusicListType(PageType::LOCAL_PAGE);
    ui->localPage->reFresh(musicList);
    ui->recentPage->setMusicListType(PageType::HISTORY_PAGE);
    ui->recentPage->reFresh(musicList);
}

void MusicPlayer::updateBtformAnimation()
{
    int index = ui->stackedWidget->indexOf(currentPage);
    if (index == -1)
    {
        qDebug() << "页面不存在";
        return;
    }

    // 获取btFrom
    QList<BtForm*> btForm = this->findChildren<BtForm*>();
    for (auto form : btForm)
    {
        if (form->getPageId() == index)
        {
            form->showAnimation(true);
        }
        else
        {
            form->showAnimation(false);
        }
    }
}

void MusicPlayer::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isDrag = true;
        // event->globalPos()：鼠标按下时，光标相对于
        // 屏幕左上位置frameGeometry().topLeft()
        // geometry(): 不包括边框及顶部标题区的范围
        dragPosition = event->globalPos() - geometry().topLeft();
        return;
    }

    QWidget::mousePressEvent(event);
}

void MusicPlayer::mouseMoveEvent(QMouseEvent *event)
{
    // 按钮位置不能移动
    if (event->buttons() == Qt::LeftButton && isDrag)
    {
        // 根据鼠标移动更新窗口位置
        this->move(event->globalPos() - dragPosition);
        return;
    }

    QWidget::mouseMoveEvent(event);
}


void MusicPlayer::on_quit_clicked()
{
    this->hide();
}

void MusicPlayer::onBtFormClick(int pageId)
{
    // 清除其他颜色
    // 获取所有BtForm按钮
    QList<BtForm*> btFormList = findChildren<BtForm*>();
    for (auto btForm : btFormList)
    {
        if (pageId != btForm->getPageId())
        btForm->clearBackground();
    }

    // 设置显示当前页面
    ui->stackedWidget->setCurrentIndex(pageId);
    // 窗口不能拖拽
    isDrag = false;
}


void MusicPlayer::on_volume_clicked()
{
    // 调整显示位置
    // 获取音量按钮左上角的坐标
    QPoint point = ui->volume->mapToGlobal(QPoint(0, 0));
    // 计算需要移动的位置，窗口显示在鼠标点击的正上方
    QPoint volumeLeftTop = point - QPoint(volumeTool->width() / 2, volumeTool->height());
    // 微调窗口位置
    volumeLeftTop.setY(volumeLeftTop.y()+30);
    volumeLeftTop.setX(volumeLeftTop.x()+15);
    // 移动
    volumeTool->move(volumeLeftTop);
    // 显示
    volumeTool->show();
}

void MusicPlayer::on_addLocal_clicked()
{
    // 打开对话框
    QFileDialog fileDialog(this, "添加音乐");
    // 设置过滤器
    QStringList mimeList;
    mimeList << "application/octet-stream";
    fileDialog.setMimeTypeFilters(mimeList);
    // 设置对话框模式，一次性选择多个文件
    fileDialog.setFileMode(QFileDialog::ExistingFiles);
//    // 设置默认路径
//    QDir dir(QDir::currentPath());
//    dir.cdUp();
//    QString path = dir.path() + "/MusicPlayer/musics";
//    fileDialog.setDirectory(path);
    // 获取结果
    if (fileDialog.exec() == QFileDialog::Accepted)
    {
        ui->stackedWidget->setCurrentIndex(4);
        QList<QUrl> urls = fileDialog.selectedUrls();
        // 拿到歌曲文件，交给musicList管理
        musicList.addMusicByUrl(urls);
        // 设置显示到本地页面
        ui->stackedWidget->setCurrentIndex(4);
        // 显示到界面上
        ui->localPage->reFresh(musicList);
        // 加载到媒体播放列表
        ui->localPage->addMusicToPlayer(musicList, playList);
    }
}

void MusicPlayer::onUpdateLikeMusic(bool isLike, QString musicId)
{
    // 找到这首歌
    auto it = musicList.findMusicByMusicId(musicId);
    if (it != musicList.end())
    {
        it->setIsLike(isLike);
    }

    // 三个页面更新数据
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}



void MusicPlayer::on_Play_clicked()
{
    // 播放状态切换
    if (player->state() == QMediaPlayer::PlayingState)
    {
        // 正在播放就暂停
        player->pause();
    }
    else if (player->state() == QMediaPlayer::PausedState)
    {
        // 暂停继续播放
        player->play();
    }
    else
    {
        // 停止等其他状态都播放
        player->play();
    }
}

void MusicPlayer::onPlayStateChanged()
{
    if (player->state() == QMediaPlayer::PlayingState)
    {
        // 播放状态
        ui->Play->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        ui->Play->setIcon(QIcon(":/images/play3.png"));
    }
}

void MusicPlayer::on_playUp_clicked()
{
    playList->previous();
}

void MusicPlayer::on_playDown_clicked()
{
    playList->next();
}

void MusicPlayer::on_playMode_clicked()
{
    if (playList->playbackMode() == QMediaPlaylist::Loop)
    {
        // 列表循环
        ui->playMode->setToolTip("随机播放");
        playList->setPlaybackMode(QMediaPlaylist::Random);
    }
    else if (playList->playbackMode() == QMediaPlaylist::Random)
    {
        // 随机播放
        ui->playMode->setToolTip("单曲循环");
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
    else if (playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop)
    {
        // 列表循环
        ui->playMode->setToolTip("列表循环");
        playList->setPlaybackMode(QMediaPlaylist::Loop);
    }
    else
    {
        qDebug() << playList->errorString();
    }
}

void MusicPlayer::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode == QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/images/list_play.png"));
    } else if(playbackMode == QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    } else if(playbackMode == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/images/single_play.png"));
    } else {
        qDebug()<<"暂不支持该模式";
    }
}

void MusicPlayer::onPlayAll(PageType pageType)
{
    CommonPage* page = ui->localPage;
    switch(pageType)
    {
        case PageType::LIKE_PAGE:
        page = ui->likePage;
        break;
        case PageType::LOCAL_PAGE:
        page = ui->localPage;
        break;
        case PageType::HISTORY_PAGE:
        page = ui->recentPage;
        break;
        default:
        qDebug()<<"扩展";
    }
    // 从当前页面的零号位置开始播放
    playAllOfCommonPage(page, 0);
}

void MusicPlayer::playAllOfCommonPage(CommonPage *commonPage, int index)
{
    // 更新页面
    currentPage = commonPage;
    updateBtformAnimation();
    // 先清空
    playList->clear();
    // 当前页面歌曲添加到播放列表
    commonPage->addMusicToPlayer(musicList, playList);
    // 设置索引
    playList->setCurrentIndex(index);
    // 播放
    player->play();
}

void MusicPlayer::playMusicByIndex(CommonPage *page, int index)
{
    playAllOfCommonPage(page, index);
}

void MusicPlayer::onCurrentIndexChanged(int index)
{
    currentIndex = index;
    // 先找到音乐id
    const QString& musicId = currentPage->getMusicIdByIndex(index);
    auto it = musicList.findMusicByMusicId(musicId);
    if (it != musicList.end())
    {
        // 设置为历史播放
        it->setIsHistory(true);
    }

    ui->recentPage->reFresh(musicList);
}

void MusicPlayer::setMusicSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

void MusicPlayer::setPlayerVolume(int volume)
{
    player->setVolume(volume);
}

void MusicPlayer::onDurationChanged(qint64 duration)
{
    totalTime = duration;
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                           .arg(duration/1000%60, 2, 10, QChar('0')));

}

void MusicPlayer::onPositionChanged(qint64 duration)
{
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                             .arg(duration/1000%60, 2, 10, QChar('0')));

    ui->processBar->setStep(duration / (float)totalTime);
    // 显示歌词
    if (currentIndex >= 0)
    {
       lrcPage->showLrcWord(duration);
    }
}

void MusicPlayer::onMusicSliderChanged(float value)
{
    // 当前播放位置时长
    qint64 duration = totalTime * value;
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                             .arg(duration/1000%60, 2, 10, QChar('0')));;
    // 设置播放位置
    player->setPosition(duration);
}

void MusicPlayer::onMetaDataAvailableChanged(bool available)
{
    (void)available;
    // 从保存的列表里获取音乐数据
    QString musicId = currentPage->getMusicIdByIndex(currentIndex);
    auto it = musicList.findMusicByMusicId(musicId);
    QString musicName = "未知歌曲";
    QString singer = "未知歌手";

    if (it != musicList.end())
    {
         musicName = it->getMusicName();
         singer = it->getSingerName();
         // 记载歌词并展示
         lrcPage->parseLrc(it->getLrcFilePath());
         lrcPage->setTitle(musicName, singer);
    }

    ui->musicName->setText(musicName);
    ui->musicSinger->setText(singer);
    // 获取图片
    QVariant coverImage = player->metaData("ThumbnailImage");
    if (coverImage.isValid())
    {
        // 获取成功
        QImage image = coverImage.value<QImage>();
        // 设置
        ui->musicCover->setPixmap(QPixmap::fromImage(image));
        currentPage->setImageLabel(QPixmap::fromImage(image));
    }
    else
    {
        // 设置默认图片
        ui->musicCover->setPixmap(QString(":/images/rec/009.png"));
        currentPage->setImageLabel(QString(":/images/rec/009.png"));
    }
    // 缩放填充
    ui->musicCover->setScaledContents(true);
}

void MusicPlayer::on_lrcWord_clicked()
{
    lrcPage->show();
    lrcAnimation->start();
//    // 动画结束释放
//    connect(animation, &QPropertyAnimation::finished, this, [=](){
//        delete animation;
//    });
}

void MusicPlayer::on_pushButton_clicked()
{
    isSpeed = !isSpeed;
    if (isSpeed)
    {
        player->setPlaybackRate(speed);
    }
    else
    {
        player->setPlaybackRate(1.0);
    }
}

void MusicPlayer::on_skin_clicked()
{
    QMessageBox::information(this, "提示", "未支持");
}

void MusicPlayer::on_min_clicked()
{
    showMinimized();
}

void MusicPlayer::quitMusicPlayer()
{
    // 更新数据库
    musicList.writeToDB();
    sqlite.close();
    this->close();
}
